home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume15 / twm / part02 < prev    next >
Encoding:
Internet Message Format  |  1988-06-12  |  59.9 KB

  1. Subject:  v15i065:  A window manager for X, Part02/04
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Tom LaStrange <esunix!tlastran>
  7. Posting-number: Volume 15, Issue 65
  8. Archive-name: twm/part02
  9.  
  10.  
  11.  
  12. #! /bin/sh
  13. # This is a shell archive, meaning:
  14. # 1.  Remove everything above the #! /bin/sh line.
  15. # 2.  Save the resulting test in a file
  16. # 3.  Execute the file with /bin/sh (not csh) to create the files:
  17. #
  18. #menus.c
  19. #events.c
  20. #resize.c
  21. #util.c
  22. #version.c
  23. #
  24. #
  25. if test -f 'menus.c'
  26. then
  27.     echo shar: will not over-write existing file "menus.c"
  28. else
  29. echo extracting "menus.c"
  30. sed 's/^X//' >menus.c <<'SHAR_EOF'
  31. X/*****************************************************************************/
  32. X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
  33. X/**                          Salt Lake City, Utah                           **/
  34. X/**                                                                         **/
  35. X/**                           All Rights Reserved                           **/
  36. X/**                                                                         **/
  37. X/**    Permission to use, copy, modify, and distribute this software and    **/
  38. X/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
  39. X/**    granted, provided that the above copyright notice appear  in  all    **/
  40. X/**    copies and that both  that  copyright  notice  and  this  permis-    **/
  41. X/**    sion  notice appear in supporting  documentation,  and  that  the    **/
  42. X/**    name  of Evans & Sutherland  not be used in advertising or publi-    **/
  43. X/**    city pertaining to distribution  of the software without  specif-    **/
  44. X/**    ic, written prior permission.                                        **/
  45. X/**                                                                         **/
  46. X/**    EVANS  & SUTHERLAND  DISCLAIMS  ALL  WARRANTIES  WITH  REGARD  TO    **/
  47. X/**    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI-    **/
  48. X/**    TY AND FITNESS, IN NO EVENT SHALL EVANS &  SUTHERLAND  BE  LIABLE    **/
  49. X/**    FOR  ANY  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY  DAM-    **/
  50. X/**    AGES  WHATSOEVER RESULTING FROM  LOSS OF USE,  DATA  OR  PROFITS,    **/
  51. X/**    WHETHER   IN  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS    **/
  52. X/**    ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE  OR PER-    **/
  53. X/**    FORMANCE OF THIS SOFTWARE.                                           **/
  54. X/*****************************************************************************/
  55. X
  56. X/***********************************************************************
  57. X *
  58. X * $Header: menus.c,v 1.20 88/04/15 07:09:54 tlastran Exp $
  59. X *
  60. X * twm menu code
  61. X *
  62. X * 17-Nov-87 Thomas E. LaStrange        File created
  63. X *
  64. X ***********************************************************************/
  65. X
  66. X#ifndef lint
  67. Xstatic char RCSinfo[] =
  68. X"$Header: menus.c,v 1.20 88/04/15 07:09:54 tlastran Exp $";
  69. X#endif
  70. X
  71. X#include <stdio.h>
  72. X#include <signal.h>
  73. X#include "twm.h"
  74. X#include "gc.h"
  75. X#include "menus.h"
  76. X#include "events.h"
  77. X#include "util.h"
  78. X#include "gram.h"
  79. X
  80. X#include "pull.bm"
  81. X
  82. XMenuRoot *Menu[MAX_BUTTONS + 1];    /* one root per button */
  83. XMenuItem *Item[MAX_BUTTONS + 1];    /* one action per button */
  84. XMenuRoot *MenuList = NULL;        /* head of the menu list */
  85. XMenuRoot *LastMenu = NULL;        /* the last menu */
  86. XMenuRoot *ActiveMenu = NULL;        /* the active menu */
  87. XMenuItem *ActiveItem = NULL;        /* the active menu item */
  88. X
  89. X/***********************************************************************
  90. X *
  91. X *  Procedure:
  92. X *    InitMenus - initialize menu roots
  93. X *
  94. X ***********************************************************************
  95. X */
  96. X
  97. Xvoid
  98. XInitMenus()
  99. X{
  100. X    int i;
  101. X
  102. X    for (i = 0; i < (MAX_BUTTONS + 1); i++)
  103. X    {
  104. X    Menu[i] = NULL;
  105. X    Item[i] = NULL;
  106. X    }
  107. X}
  108. X
  109. X/***********************************************************************
  110. X *
  111. X *  Procedure:
  112. X *    NewMenuRoot - create a new menu root
  113. X *
  114. X *  Returned Value:
  115. X *    (MenuRoot *)
  116. X *
  117. X *  Inputs:
  118. X *    name    - the name of the menu root
  119. X *
  120. X ***********************************************************************
  121. X */
  122. X
  123. XMenuRoot *
  124. XNewMenuRoot(name)
  125. X    char *name;
  126. X{
  127. X    MenuRoot *tmp;
  128. X
  129. X    CreateGCs();
  130. X
  131. X    tmp = (MenuRoot *) malloc(sizeof(MenuRoot));
  132. X    tmp->name = name;
  133. X    tmp->prev = NULL;
  134. X    tmp->first = NULL;
  135. X    tmp->last = NULL;
  136. X    tmp->items = 0;
  137. X    tmp->width = 0;
  138. X    tmp->mapped = FALSE;
  139. X    tmp->pull = FALSE;
  140. X    tmp->active = TRUE;
  141. X    tmp->shadow = XCreateSimpleWindow(dpy, Root,
  142. X    0, 0, 10, 10, 1, Foreground, Foreground);
  143. X    tmp->w = XCreateSimpleWindow(dpy, Root,
  144. X    0, 0, 10, 10, 1, Foreground, Background);
  145. X    XSelectInput(dpy, tmp->w, LeaveWindowMask);
  146. X
  147. X    if (MenuList == NULL)
  148. X    {
  149. X    MenuList = tmp;
  150. X    MenuList->next = NULL;
  151. X    }
  152. X
  153. X    if (LastMenu == NULL)
  154. X    {
  155. X    LastMenu = tmp;
  156. X    LastMenu->next = NULL;
  157. X    }
  158. X    else
  159. X    {
  160. X    LastMenu->next = tmp;
  161. X    LastMenu = tmp;
  162. X    LastMenu->next = NULL;
  163. X    }
  164. X
  165. X    return (tmp);
  166. X}
  167. X
  168. X/***********************************************************************
  169. X *
  170. X *  Procedure:
  171. X *    AddToMenu - add an item to a root menu
  172. X *
  173. X *  Returned Value:
  174. X *    (MenuItem *)
  175. X *
  176. X *  Inputs:
  177. X *    menu    - pointer to the root menu to add the item
  178. X *    item    - the text to appear in the menu
  179. X *    action    - the string to possibly execute
  180. X *    sub    - the menu root if it is a pull-right entry
  181. X *    func    - the numeric function
  182. X *
  183. X ***********************************************************************
  184. X */
  185. X
  186. XMenuItem *
  187. XAddToMenu(menu, item, action, sub, func)
  188. X    MenuRoot *menu;
  189. X    char *item, *action;
  190. X    MenuRoot *sub;
  191. X    int func;
  192. X{
  193. X    unsigned long valuemask;
  194. X    XSetWindowAttributes attributes;
  195. X    MenuItem *tmp;
  196. X    int width;
  197. X
  198. X#ifdef DEBUG
  199. X    fprintf(stderr, "adding menu item=\"%s\", action=%s, sub=%d, f=%d\n",
  200. X    item, action, sub, func);
  201. X#endif
  202. X
  203. X    tmp = (MenuItem *) malloc(sizeof(MenuItem));
  204. X    tmp->root = menu;
  205. X
  206. X    if (menu->first == NULL)
  207. X    {
  208. X    menu->first = tmp;
  209. X    tmp->prev = NULL;
  210. X    }
  211. X    else
  212. X    {
  213. X    menu->last->next = tmp;
  214. X    tmp->prev = menu->last;
  215. X    }
  216. X    menu->last = tmp;
  217. X
  218. X    tmp->item = item;
  219. X    tmp->action = action;
  220. X    tmp->next = NULL;
  221. X    tmp->sub = NULL;
  222. X    tmp->pull = NULL;
  223. X    tmp->state = 0;
  224. X    tmp->func = func;
  225. X
  226. X    width = XTextWidth(MenuFont, item, strlen(item));
  227. X    if (width > menu->width)
  228. X    menu->width = width;
  229. X
  230. X    if (tmp->func != F_TITLE)
  231. X    {
  232. X    tmp->w = XCreateSimpleWindow(dpy, menu->w,
  233. X        0, menu->items * (MenuFontHeight + 4),
  234. X        width, MenuFontHeight + 4,
  235. X        0,
  236. X        Foreground, Background);
  237. X    XSelectInput(dpy, tmp->w, EnterWindowMask
  238. X        | LeaveWindowMask | ExposureMask);
  239. X    }
  240. X    else
  241. X    {
  242. X    tmp->w = XCreateSimpleWindow(dpy, menu->w,
  243. X        -1, menu->items * (MenuFontHeight + 4),
  244. X        width, MenuFontHeight + 2,
  245. X        1,
  246. X        Foreground, Background);
  247. X    XSelectInput(dpy, tmp->w, ExposureMask);
  248. X    }
  249. X
  250. X    if (sub != NULL)
  251. X    {
  252. X    Pixmap pm;
  253. X
  254. X    tmp->sub = sub;
  255. X    pm = MakePixmap(tmp->w, MenuNormalGC,
  256. X        pull_bits, pull_width, pull_height);
  257. X
  258. X    valuemask = CWEventMask | CWBackPixmap;
  259. X    attributes.background_pixmap = pm;
  260. X    attributes.event_mask = EnterWindowMask | LeaveWindowMask;
  261. X
  262. X    tmp->pull = XCreateWindow(dpy, tmp->w,
  263. X        0, 0,
  264. X        pull_width, pull_height,
  265. X        0, DefaultDepth(dpy, 0), CopyFromParent, DefaultVisual(dpy, 0),
  266. X        valuemask, &attributes);
  267. X
  268. X    XMapWindow(dpy, tmp->pull);
  269. X
  270. X    menu->pull = TRUE;
  271. X    XSaveContext(dpy, tmp->pull, MenuContext, tmp);
  272. X    }
  273. X    menu->items += 1;
  274. X
  275. X    XSaveContext(dpy, tmp->w, MenuContext, tmp);
  276. X
  277. X    if (menu->items == 1)
  278. X    XSaveContext(dpy, tmp->root->w, MenuContext, tmp);
  279. X
  280. X    return (tmp);
  281. X}
  282. X
  283. X/***********************************************************************
  284. X *
  285. X *  Procedure:
  286. X *    PopUpMenu - pop up a pull down menu
  287. X *
  288. X *  Inputs:
  289. X *    menu    - the root pointer of the menu to pop up
  290. X *    x    - the x location of the mouse
  291. X *    y    - the y location of the mouse
  292. X *
  293. X ***********************************************************************
  294. X */
  295. X
  296. Xvoid
  297. XPopUpMenu(menu, x, y)
  298. X    MenuRoot *menu;
  299. X    int x, y;
  300. X{
  301. X    int d_width, d_height, m_height;
  302. X    XWindowChanges xwc, pwc;
  303. X    unsigned int xwcm, pwcm;
  304. X    MenuItem *tmp;
  305. X
  306. X    if (ActiveMenu != NULL)
  307. X    ActiveMenu->active = FALSE;
  308. X
  309. X    menu->active = TRUE;
  310. X    ActiveMenu = menu;
  311. X    if (menu->mapped != TRUE)
  312. X    {
  313. X    if (menu->pull == TRUE)
  314. X    {
  315. X        menu->width += pull_width + 10;
  316. X    }
  317. X
  318. X    xwcm = 0;
  319. X    xwcm |= CWWidth;
  320. X    xwc.width = menu->width + 10;
  321. X
  322. X    pwcm = 0;
  323. X    pwcm |= CWX;
  324. X    pwc.x = xwc.width - pull_width;
  325. X
  326. X    for (tmp = menu->first; tmp != NULL; tmp = tmp->next)
  327. X    {
  328. X        XConfigureWindow(dpy, tmp->w, xwcm, &xwc);
  329. X        if (tmp->pull != NULL)
  330. X        {
  331. X        XConfigureWindow(dpy, tmp->pull, pwcm, &pwc);
  332. X        }
  333. X        if (tmp->func != F_TITLE)
  334. X        tmp->y = 5;
  335. X        else
  336. X        {
  337. X        tmp->y = xwc.width - XTextWidth(MenuFont, tmp->item,
  338. X            strlen(tmp->item));
  339. X        tmp->y /= 2;
  340. X        }
  341. X    }
  342. X    }
  343. X    menu->mapped = TRUE;
  344. X
  345. X    d_width = DisplayWidth(dpy, DefaultScreen(dpy));
  346. X    d_height = DisplayHeight(dpy, DefaultScreen(dpy));
  347. X    m_height = menu->items * (MenuFontHeight + 4);
  348. X
  349. X    if ((x + menu->width + 10) > d_width)
  350. X    x = (d_width - menu->width - 20);
  351. X
  352. X    if ((y + m_height + 10) > d_height)
  353. X    y = (d_height - m_height - 20);
  354. X
  355. X    xwcm = 0;
  356. X    xwcm |= CWX;
  357. X    xwc.x = x - 1;
  358. X    xwcm |= CWY;
  359. X    xwc.y = y - ((MenuFontHeight + 4) / 2);
  360. X    xwcm |= CWWidth;
  361. X    xwc.width = menu->width + 10;
  362. X    xwcm |= CWHeight;
  363. X    xwc.height = m_height;
  364. X
  365. X    XConfigureWindow(dpy, menu->w, xwcm, &xwc);
  366. X
  367. X    xwc.x = xwc.x + 5;
  368. X    xwc.y = xwc.y + 5;
  369. X    /* xwc.width -= 20; xwc.height -= 20; */
  370. X
  371. X    XConfigureWindow(dpy, menu->shadow, xwcm, &xwc);
  372. X    XWarpPointer(dpy, None, menu->w, 0, 0, 0, 0, 1, (MenuFontHeight + 4) / 2);
  373. X    XMapSubwindows(dpy, menu->w);
  374. X    XRaiseWindow(dpy, menu->shadow);
  375. X    XMapRaised(dpy, menu->w);
  376. X    XMapWindow(dpy, menu->shadow);
  377. X}
  378. X
  379. X/***********************************************************************
  380. X *
  381. X *  Procedure:
  382. X *    FindMenuRoot - look for a menu root
  383. X *
  384. X *  Returned Value:
  385. X *    (MenuRoot *)  - a pointer to the menu root structure 
  386. X *
  387. X *  Inputs:
  388. X *    name    - the name of the menu root 
  389. X *
  390. X ***********************************************************************
  391. X */
  392. X
  393. XMenuRoot *
  394. XFindMenuRoot(name)
  395. X    char *name;
  396. X{
  397. X    MenuRoot *tmp;
  398. X
  399. X    for (tmp = MenuList; tmp != NULL; tmp = tmp->next)
  400. X    {
  401. X    if (strcmp(name, tmp->name) == 0)
  402. X        return (tmp);
  403. X    }
  404. X    return NULL;
  405. X}
  406. X
  407. X/***********************************************************************
  408. X *
  409. X *  Procedure:
  410. X *    ExecuteFunction - execute a twm root function
  411. X *
  412. X *  Inputs:
  413. X *    menu - the menu item to execute 
  414. X *
  415. X ***********************************************************************
  416. X */
  417. X
  418. Xvoid
  419. XExecuteFunction(menu)
  420. X    MenuItem *menu;
  421. X{
  422. X    Window w;
  423. X    unsigned long black;
  424. X    char tmp[200];
  425. X    char *ptr;
  426. X    int len;
  427. X    char buff[MAX_FILE_SIZE];
  428. X    int count, fd;
  429. X    MenuRoot *root, *tmp_root;
  430. X    MenuItem *item, *tmp_item;
  431. X
  432. X    XGrabPointer(dpy, Root, True,
  433. X    ButtonReleaseMask | ButtonMotionMask,
  434. X    GrabModeAsync, GrabModeSync,
  435. X    Root, ClockCursor, CurrentTime);
  436. X
  437. X    switch (menu->func)
  438. X    {
  439. X    case F_NOP:
  440. X    case F_TITLE:
  441. X    break;
  442. X
  443. X    case F_CIRCLEUP:
  444. X    XCirculateSubwindowsUp(dpy, Root);
  445. X    break;
  446. X
  447. X    case F_CIRCLEDOWN:
  448. X    XCirculateSubwindowsDown(dpy, Root);
  449. X    break;
  450. X
  451. X    case F_VERSION:
  452. X    XMapRaised(dpy, VersionWindow);
  453. X    break;
  454. X
  455. X    case F_EXEC:
  456. X    Execute(menu->action);
  457. X    break;
  458. X
  459. X    case F_FOCUS:
  460. X    FocusOnRoot();
  461. X    break;
  462. X
  463. X    case F_CUT:
  464. X    strcpy(tmp, menu->action);
  465. X    strcat(tmp, "\n");
  466. X    XStoreBytes(dpy, tmp, strlen(tmp));
  467. X    break;
  468. X
  469. X    case F_CUTFILE:
  470. X    ptr = XFetchBytes(dpy, &count);
  471. X    if (count != 0)
  472. X    {
  473. X        if (sscanf(ptr, "%s", tmp) == 1)
  474. X        {
  475. X        fd = open(tmp, 0);
  476. X        if (fd >= 0)
  477. X        {
  478. X            count = read(fd, buff, MAX_FILE_SIZE - 1);
  479. X            if (count > 0)
  480. X            XStoreBytes(dpy, buff, strlen(buff));
  481. X
  482. X            close(fd);
  483. X        }
  484. X        else
  485. X        {
  486. X            fprintf(stderr, "twm: couldn't open \"%s\"\n", tmp);
  487. X        }
  488. X        }
  489. X        XFree(ptr);
  490. X    }
  491. X    else
  492. X    {
  493. X        fprintf(stderr, "twm: nothing in the cut buffer\n");
  494. X    }
  495. X    break;
  496. X
  497. X    case F_FILE:
  498. X    fd = open(menu->action, 0);
  499. X    if (fd >= 0)
  500. X    {
  501. X        count = read(fd, buff, MAX_FILE_SIZE - 1);
  502. X        if (count > 0)
  503. X        XStoreBytes(dpy, buff, strlen(buff));
  504. X
  505. X        close(fd);
  506. X    }
  507. X    else
  508. X    {
  509. X        fprintf(stderr, "twm: couldn't open \"%s\"\n", menu->action);
  510. X    }
  511. X    break;
  512. X
  513. X    case F_TWMRC:
  514. X    len = strlen(menu->action);
  515. X    if (len == 0)
  516. X        ptr = NULL;
  517. X    else
  518. X    {
  519. X        ptr = (char *)malloc(len+1);
  520. X        if (ptr == NULL)
  521. X        {
  522. X        fprintf(stderr, "twm: out of memory\n");
  523. X        exit(1);
  524. X        }
  525. X        strcpy(ptr, menu->action);
  526. X    }
  527. X
  528. X    /* first get rid of the existing menu structure and destroy all
  529. X     * windows */
  530. X    for (root = MenuList; root != NULL;)
  531. X    {
  532. X        for (item = root->last; item != NULL;)
  533. X        {
  534. X        if (item->pull != NULL)
  535. X        {
  536. X            XDeleteContext(dpy, item->pull, MenuContext);
  537. X            XDestroyWindow(dpy, item->pull);
  538. X        }
  539. X        XDeleteContext(dpy, item->w, MenuContext);
  540. X        XDestroyWindow(dpy, item->w);
  541. X
  542. X        free(item->item);
  543. X        free(item->action);
  544. X
  545. X        tmp_item = item;
  546. X        item = item->prev;
  547. X        free(tmp_item);
  548. X        }
  549. X
  550. X        XDeleteContext(dpy, root->w, MenuContext);
  551. X        XDestroyWindow(dpy, root->shadow);
  552. X        XDestroyWindow(dpy, root->w);
  553. X        free(root->name);
  554. X
  555. X        tmp_root = root;
  556. X        root = root->next;
  557. X        free(tmp_root);
  558. X    }
  559. X    MenuList = NULL;
  560. X    LastMenu = NULL;
  561. X    ActiveMenu = NULL;
  562. X    ActiveItem = NULL;
  563. X
  564. X    ParseTwmrc(ptr);
  565. X    break;
  566. X
  567. X    case F_REFRESH:
  568. X    black = BlackPixel(dpy, DefaultScreen(dpy));
  569. X    w = XCreateSimpleWindow(dpy, Root,
  570. X        0, 0, 9999, 9999, 0, black, black);
  571. X    XMapWindow(dpy, w);
  572. X    XDestroyWindow(dpy, w);
  573. X    XFlush(dpy);
  574. X    break;
  575. X
  576. X    case F_QUIT:
  577. X    Done();
  578. X    break;
  579. X    }
  580. X}
  581. X
  582. X/***********************************************************************
  583. X *
  584. X *  Procedure:
  585. X *    Execute - execute the string by /bin/sh
  586. X *
  587. X *  Inputs:
  588. X *    s    - the string containing the command
  589. X *
  590. X ***********************************************************************
  591. X */
  592. X
  593. Xvoid
  594. XExecute(s)
  595. X    char *s;
  596. X{
  597. X    int status, pid, w;
  598. X    register int (*istat) (), (*qstat) ();
  599. X
  600. X    if ((pid = vfork()) == 0)
  601. X    {
  602. X    signal(SIGINT, SIG_DFL);
  603. X    signal(SIGQUIT, SIG_DFL);
  604. X    signal(SIGHUP, SIG_DFL);
  605. X    execl("/bin/sh", "sh", "-c", s, 0);
  606. X    _exit(127);
  607. X    }
  608. X    istat = signal(SIGINT, SIG_IGN);
  609. X    qstat = signal(SIGQUIT, SIG_IGN);
  610. X    while ((w = wait(&status)) != pid && w != -1);
  611. X    if (w == -1)
  612. X    status = -1;
  613. X    signal(SIGINT, istat);
  614. X    signal(SIGQUIT, qstat);
  615. X}
  616. X
  617. X/***********************************************************************
  618. X *
  619. X *  Procedure:
  620. X *    FocusOnRoot - put input focus on the root window
  621. X *
  622. X ***********************************************************************
  623. X */
  624. X
  625. Xvoid
  626. XFocusOnRoot()
  627. X{
  628. X    XSetInputFocus(dpy, Root, RevertToPointerRoot, CurrentTime);
  629. X    if (Focus != NULL)
  630. X    {
  631. X    XUnmapWindow(dpy, Focus->hilite_w);
  632. X    }
  633. X    Focus = NULL;
  634. X    FocusRoot = TRUE;
  635. X}
  636. SHAR_EOF
  637. if test 13977 -ne "`wc -c < menus.c`"
  638. then
  639.     echo shar: error transmitting "menus.c" '(should have been 13977 characters)'
  640. fi
  641. fi
  642. if test -f 'events.c'
  643. then
  644.     echo shar: will not over-write existing file "events.c"
  645. else
  646. echo extracting "events.c"
  647. sed 's/^X//' >events.c <<'SHAR_EOF'
  648. X/*****************************************************************************/
  649. X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
  650. X/**                          Salt Lake City, Utah                           **/
  651. X/**                                                                         **/
  652. X/**                           All Rights Reserved                           **/
  653. X/**                                                                         **/
  654. X/**    Permission to use, copy, modify, and distribute this software and    **/
  655. X/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
  656. X/**    granted, provided that the above copyright notice appear  in  all    **/
  657. X/**    copies and that both  that  copyright  notice  and  this  permis-    **/
  658. X/**    sion  notice appear in supporting  documentation,  and  that  the    **/
  659. X/**    name  of Evans & Sutherland  not be used in advertising or publi-    **/
  660. X/**    city pertaining to distribution  of the software without  specif-    **/
  661. X/**    ic, written prior permission.                                        **/
  662. X/**                                                                         **/
  663. X/**    EVANS  & SUTHERLAND  DISCLAIMS  ALL  WARRANTIES  WITH  REGARD  TO    **/
  664. X/**    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI-    **/
  665. X/**    TY AND FITNESS, IN NO EVENT SHALL EVANS &  SUTHERLAND  BE  LIABLE    **/
  666. X/**    FOR  ANY  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY  DAM-    **/
  667. X/**    AGES  WHATSOEVER RESULTING FROM  LOSS OF USE,  DATA  OR  PROFITS,    **/
  668. X/**    WHETHER   IN  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS    **/
  669. X/**    ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE  OR PER-    **/
  670. X/**    FORMANCE OF THIS SOFTWARE.                                           **/
  671. X/*****************************************************************************/
  672. X
  673. X/***********************************************************************
  674. X *
  675. X * $Header: events.c,v 1.31 88/04/15 07:09:47 tlastran Exp $
  676. X *
  677. X * twm event handling
  678. X *
  679. X * 17-Nov-87 Thomas E. LaStrange        File created
  680. X *
  681. X ***********************************************************************/
  682. X
  683. X#ifndef lint
  684. Xstatic char RCSinfo[]=
  685. X"$Header: events.c,v 1.31 88/04/15 07:09:47 tlastran Exp $";
  686. X#endif
  687. X
  688. X#include <stdio.h>
  689. X#include "twm.h"
  690. X#include "add_window.h"
  691. X#include "menus.h"
  692. X#include "events.h"
  693. X#include "resize.h"
  694. X#include "gram.h"
  695. X
  696. X#include "twm.bm"
  697. X
  698. Xstatic event_proc EventHandler[LASTEvent]; /* event handler jump table */
  699. Xstatic XEvent event;        /* the current event */
  700. Xstatic TwmWindow *tmp_win;    /* the current twm window */
  701. Xstatic Window w;        /* the window that caused the event */
  702. X
  703. Xstatic int ConstMove = FALSE;    /* constrained move variables */
  704. Xstatic int ConstMoveDir;
  705. Xstatic int ConstMoveX;
  706. Xstatic int ConstMoveY;
  707. Xstatic int ConstMoveXL;
  708. Xstatic int ConstMoveXR;
  709. Xstatic int ConstMoveYT;
  710. Xstatic int ConstMoveYB;
  711. X
  712. X#define MOVE_NONE    0    /* modes of constrained move */
  713. X#define MOVE_VERT    1
  714. X#define MOVE_HORIZ    2
  715. X
  716. Xstatic Window DragWindow;    /* variables used in moving windows */
  717. Xstatic int DragX;
  718. Xstatic int DragY;
  719. Xstatic int DragWidth;
  720. Xstatic int DragHeight;
  721. Xstatic int enter_flag;
  722. X
  723. X
  724. X/***********************************************************************
  725. X *
  726. X *  Procedure:
  727. X *    InitEvents - initialize the event jump table
  728. X *
  729. X ***********************************************************************
  730. X */
  731. X
  732. Xvoid
  733. XInitEvents()
  734. X{
  735. X    int i;
  736. X
  737. X    ResizeWindow = NULL;
  738. X    DragWindow = NULL;
  739. X    enter_flag = FALSE;
  740. X
  741. X    for (i = 0; i < LASTEvent; i++)
  742. X    EventHandler[i] = HandleUnknown;
  743. X
  744. X    EventHandler[Expose] = HandleExpose;
  745. X    EventHandler[DestroyNotify] = HandleDestroyNotify;
  746. X    EventHandler[MapRequest] = HandleMapRequest;
  747. X    EventHandler[MapNotify] = HandleMapNotify;
  748. X    EventHandler[UnmapNotify] = HandleUnmapNotify;
  749. X    EventHandler[MotionNotify] = HandleMotionNotify;
  750. X    EventHandler[ButtonRelease] = HandleButtonRelease;
  751. X    EventHandler[ButtonPress] = HandleButtonPress;
  752. X    EventHandler[EnterNotify] = HandleEnterNotify;
  753. X    EventHandler[LeaveNotify] = HandleLeaveNotify;
  754. X    EventHandler[ConfigureNotify] = HandleConfigureNotify;
  755. X    EventHandler[ClientMessage] = HandleClientMessage;
  756. X}
  757. X
  758. X/***********************************************************************
  759. X *
  760. X *  Procedure:
  761. X *    HandleEvents - handle X events
  762. X *
  763. X ***********************************************************************
  764. X */
  765. X
  766. Xvoid
  767. XHandleEvents()
  768. X{
  769. X    InitEvents();
  770. X
  771. X    while (TRUE)
  772. X    {
  773. X    XNextEvent(dpy, &event);
  774. X    w = event.xany.window;
  775. X    if (XFindContext(dpy, w, TwmContext, &tmp_win) == XCNOENT)
  776. X        tmp_win = NULL;
  777. X
  778. X#ifdef DEBUG
  779. X    if (event.type != MotionNotify)
  780. X    if (tmp_win != NULL)
  781. X    {
  782. X        fprintf(stderr, "Event w=%x, t->w=%x, t->frame=%x, t->title=%x, ",
  783. X        w, tmp_win->w, tmp_win->frame, tmp_win->title_w);
  784. X    }
  785. X    else
  786. X    {
  787. X        fprintf(stderr, "Event w=%x, ", w);
  788. X    }
  789. X#endif
  790. X    if (event.type >= 0 && event.type < LASTEvent)
  791. X        (*EventHandler[event.type])();
  792. X    }
  793. X}
  794. X
  795. X/***********************************************************************
  796. X *
  797. X *  Procedure:
  798. X *    HandleClientMessage - client message event handler
  799. X *
  800. X ***********************************************************************
  801. X */
  802. X
  803. Xvoid
  804. XHandleClientMessage()
  805. X{
  806. X#ifdef DEBUG
  807. X    fprintf(stderr, "ClientMessage\n");
  808. X#endif
  809. X
  810. X    enter_flag = FALSE;
  811. X}
  812. X/***********************************************************************
  813. X *
  814. X *  Procedure:
  815. X *    HandleExpose - expose event handler
  816. X *
  817. X ***********************************************************************
  818. X */
  819. X
  820. Xvoid
  821. XHandleExpose()
  822. X{
  823. X    MenuItem *tmp;
  824. X
  825. X#ifdef DEBUG
  826. X    fprintf(stderr, "Expose %d\n", event.xexpose.count);
  827. X#endif
  828. X
  829. X    if (event.xexpose.count != 0)
  830. X    return;
  831. X
  832. X    if (w == VersionWindow)
  833. X    {
  834. X    XDrawImageString(dpy, VersionWindow, VersionNormalGC,
  835. X        twm_width + 10,
  836. X        2 + VersionFont->ascent, Version, strlen(Version));
  837. X    }
  838. X
  839. X    if (tmp_win != NULL)
  840. X    {
  841. X    if (tmp_win->title_w == w)
  842. X    {
  843. X        XDrawImageString(dpy, tmp_win->title_w,
  844. X        TitleNormalGC,
  845. X        TitleBarX, TitleBarY,
  846. X        tmp_win->name, strlen(tmp_win->name));
  847. X        return;
  848. X    }
  849. X
  850. X    if (tmp_win->icon_w == w)
  851. X    {
  852. X        XDrawImageString(dpy, tmp_win->icon_w,
  853. X        IconNormalGC,
  854. X        tmp_win->icon_x, tmp_win->icon_y,
  855. X        tmp_win->icon_name, strlen(tmp_win->icon_name));
  856. X        return;
  857. X    }
  858. X    }
  859. X
  860. X    if (XFindContext(dpy, w, MenuContext, &tmp) == 0)
  861. X    {
  862. X    if (tmp->state)
  863. X        XDrawImageString(dpy,w, MenuReverseGC, tmp->y, MenuY,
  864. X        tmp->item, strlen(tmp->item));
  865. X    else
  866. X        XDrawImageString(dpy,w, MenuNormalGC, tmp->y, MenuY,
  867. X        tmp->item, strlen(tmp->item));
  868. X
  869. X    return;
  870. X    }
  871. X}
  872. X
  873. X/***********************************************************************
  874. X *
  875. X *  Procedure:
  876. X *    HandleDestroyNotify - DestroyNotify event handler
  877. X *
  878. X ***********************************************************************
  879. X */
  880. X
  881. Xvoid
  882. XHandleDestroyNotify()
  883. X{
  884. X#ifdef DEBUG
  885. X    fprintf(stderr, "DestroyNotify\n");
  886. X#endif
  887. X    if (tmp_win == NULL)
  888. X    return;
  889. X
  890. X    if (tmp_win == Focus)
  891. X    {
  892. X    FocusOnRoot();
  893. X    }
  894. X    XDeleteContext(dpy, tmp_win->w, TwmContext);
  895. X    XDeleteContext(dpy, tmp_win->frame, TwmContext);
  896. X    XDeleteContext(dpy, tmp_win->title_w, TwmContext);
  897. X    XDeleteContext(dpy, tmp_win->iconify_w, TwmContext);
  898. X    XDeleteContext(dpy, tmp_win->resize_w, TwmContext);
  899. X    XDeleteContext(dpy, tmp_win->icon_w, TwmContext);
  900. X    XDeleteContext(dpy, tmp_win->focus_w, TwmContext);
  901. X    XDeleteContext(dpy, tmp_win->hilite_w, TwmContext);
  902. X
  903. X    XDestroyWindow(dpy, tmp_win->frame);
  904. X    XDestroyWindow(dpy, tmp_win->icon_w);
  905. X    tmp_win->prev->next = tmp_win->next;
  906. X    if (tmp_win->next != NULL)
  907. X    tmp_win->next->prev = tmp_win->prev;
  908. X
  909. X    free((char *)tmp_win);
  910. X}
  911. X
  912. X/***********************************************************************
  913. X *
  914. X *  Procedure:
  915. X *    HandleMapRequest - MapRequest event handler
  916. X *
  917. X ***********************************************************************
  918. X */
  919. X
  920. Xvoid
  921. XHandleMapRequest()
  922. X{
  923. X    int stat;
  924. X    XWindowChanges xwc;
  925. X    unsigned int   xwcm;
  926. X
  927. X#ifdef DEBUG
  928. X    fprintf(stderr, "MapRequest\n");
  929. X#endif
  930. X
  931. X    stat = XFindContext(dpy, event.xmaprequest.window, TwmContext, &tmp_win);
  932. X    if (stat == XCNOENT)
  933. X    tmp_win = NULL;
  934. X
  935. X    if (tmp_win == NULL)
  936. X    {
  937. X    tmp_win = AddWindow(event.xmaprequest.window);
  938. X    if (tmp_win->wmhints && (tmp_win->wmhints->flags & StateHint))
  939. X    {
  940. X        switch (tmp_win->wmhints->initial_state)
  941. X        {
  942. X        case DontCareState:
  943. X        case NormalState:
  944. X        case ZoomState:
  945. X        case InactiveState:
  946. X            XMapWindow(dpy, event.xmaprequest.window);
  947. X            XMapRaised(dpy, tmp_win->frame);
  948. X            break;
  949. X
  950. X        case IconicState:
  951. X            xwcm = 0;
  952. X            xwcm |= CWX;
  953. X            xwcm |= CWY;
  954. X
  955. X            xwc.x = 0;
  956. X            xwc.y = 0;
  957. X
  958. X            if (tmp_win->wmhints->flags & IconPositionHint)
  959. X            {
  960. X            xwc.x = tmp_win->wmhints->icon_x;
  961. X            xwc.y = tmp_win->wmhints->icon_y;
  962. X            }
  963. X
  964. X            XConfigureWindow(dpy, tmp_win->icon_w, xwcm, &xwc);
  965. X            XMapSubwindows(dpy, tmp_win->icon_w);
  966. X            XMapRaised(dpy, tmp_win->icon_w);
  967. X            tmp_win->iconified = TRUE;
  968. X            tmp_win->icon = TRUE;
  969. X            break;
  970. X        }
  971. X    }
  972. X    else
  973. X    {
  974. X        if (!tmp_win->icon)
  975. X        {
  976. X        XMapWindow(dpy, event.xmaprequest.window);
  977. X        XMapRaised(dpy, tmp_win->frame);
  978. X        }
  979. X    }
  980. X    }
  981. X    else
  982. X    {
  983. X    if (!tmp_win->icon)
  984. X    {
  985. X        XMapWindow(dpy, event.xmaprequest.window);
  986. X        XMapRaised(dpy, tmp_win->frame);
  987. X    }
  988. X    }
  989. X    XRaiseWindow(dpy, VersionWindow);
  990. X}
  991. X
  992. X/***********************************************************************
  993. X *
  994. X *  Procedure:
  995. X *    HandleMapNotify - MapNotify event handler
  996. X *
  997. X ***********************************************************************
  998. X */
  999. X
  1000. Xvoid
  1001. XHandleMapNotify()
  1002. X{
  1003. X#ifdef DEBUG
  1004. X    fprintf(stderr, "MapNotify\n");
  1005. X#endif
  1006. X    if (tmp_win == NULL)
  1007. X    return;
  1008. X
  1009. X    XMapSubwindows(dpy, tmp_win->title_w);
  1010. X    XMapSubwindows(dpy, tmp_win->frame);
  1011. X    XUnmapWindow(dpy, tmp_win->hilite_w);
  1012. X
  1013. X    if (tmp_win->title_height == 0)
  1014. X    XUnmapWindow(dpy, tmp_win->title_w);
  1015. X
  1016. X    XMapRaised(dpy, tmp_win->frame);
  1017. X    tmp_win->mapped = TRUE;
  1018. X    XRaiseWindow(dpy, VersionWindow);
  1019. X}
  1020. X
  1021. X/***********************************************************************
  1022. X *
  1023. X *  Procedure:
  1024. X *    HandleUnmapNotify - UnmapNotify event handler
  1025. X *
  1026. X ***********************************************************************
  1027. X */
  1028. X
  1029. Xvoid
  1030. XHandleUnmapNotify()
  1031. X{
  1032. X#ifdef DEBUG
  1033. X    fprintf(stderr, "UnmapNotify\n");
  1034. X#endif
  1035. X    if (tmp_win == NULL)
  1036. X    return;
  1037. X
  1038. X    XUnmapWindow(dpy, tmp_win->frame);
  1039. X    tmp_win->mapped = FALSE;
  1040. X}
  1041. X
  1042. X/***********************************************************************
  1043. X *
  1044. X *  Procedure:
  1045. X *    HandleMotionNotify - MotionNotify event handler
  1046. X *
  1047. X ***********************************************************************
  1048. X */
  1049. X
  1050. Xvoid
  1051. XHandleMotionNotify()
  1052. X{
  1053. X#ifdef DEBUG
  1054. X    /*
  1055. X    fprintf(stderr, "MotionNotify\n");
  1056. X    */
  1057. X#endif
  1058. X    /*XUnmapWindow(dpy, VersionWindow);*/
  1059. X    if (ConstMove)
  1060. X    {
  1061. X    switch (ConstMoveDir)
  1062. X    {
  1063. X        case MOVE_NONE:
  1064. X        if (event.xbutton.x_root < ConstMoveXL ||
  1065. X            event.xbutton.x_root > ConstMoveXR)
  1066. X            ConstMoveDir = MOVE_HORIZ;
  1067. X
  1068. X        if (event.xbutton.y_root < ConstMoveYT ||
  1069. X            event.xbutton.y_root > ConstMoveYB)
  1070. X            ConstMoveDir = MOVE_VERT;
  1071. X
  1072. X        XQueryPointer(dpy, DragWindow, &JunkRoot, &JunkChild,
  1073. X            &JunkX, &JunkY, &DragX, &DragY, &JunkMask);
  1074. X        break;
  1075. X
  1076. X        case MOVE_VERT:
  1077. X        ConstMoveY = event.xbutton.y_root - DragY - BorderWidth;
  1078. X        break;
  1079. X
  1080. X        case MOVE_HORIZ:
  1081. X        ConstMoveX= event.xbutton.x_root - DragX - BorderWidth;
  1082. X        break;
  1083. X    }
  1084. X
  1085. X    if (ConstMoveDir != MOVE_NONE)
  1086. X    {
  1087. X        MoveOutline(event.xbutton.root,
  1088. X        ConstMoveX, ConstMoveY,
  1089. X        DragWidth + 2 * BorderWidth,
  1090. X        DragHeight + 2 * BorderWidth);
  1091. X    }
  1092. X    return;
  1093. X    }
  1094. X
  1095. X    if (DragWindow != NULL)
  1096. X    {
  1097. X    MoveOutline(event.xbutton.root,
  1098. X        event.xbutton.x_root - DragX - BorderWidth,
  1099. X        event.xbutton.y_root - DragY - BorderWidth,
  1100. X        DragWidth + 2 * BorderWidth,
  1101. X        DragHeight + 2 * BorderWidth);
  1102. X
  1103. X    return;
  1104. X    }
  1105. X
  1106. X    if (ResizeWindow != NULL)
  1107. X    {
  1108. X    XFindContext(dpy, ResizeWindow, TwmContext, &tmp_win);
  1109. X    DoResize(event, tmp_win);
  1110. X    }
  1111. X}
  1112. X
  1113. X/***********************************************************************
  1114. X *
  1115. X *  Procedure:
  1116. X *    HandleButtonRelease - ButtonRelease event handler
  1117. X *
  1118. X ***********************************************************************
  1119. X */
  1120. X
  1121. Xvoid
  1122. XHandleButtonRelease()
  1123. X{
  1124. X#ifdef DEBUG
  1125. X    fprintf(stderr, "ButtonRelease\n");
  1126. X#endif
  1127. X    XUngrabPointer(dpy, CurrentTime);
  1128. X    XUngrabServer(dpy);
  1129. X    EventHandler[EnterNotify] = HandleEnterNotify;
  1130. X    EventHandler[LeaveNotify] = HandleLeaveNotify;
  1131. X
  1132. X    if (DragWindow != NULL)
  1133. X    {
  1134. X    XEvent client_event;
  1135. X    XWindowChanges xwc;
  1136. X    unsigned int   xwcm;
  1137. X
  1138. X    MoveOutline(event.xbutton.root, 0, 0, 0, 0);
  1139. X
  1140. X    xwcm = 0;
  1141. X    xwcm |= CWX;
  1142. X    xwcm |= CWY;
  1143. X
  1144. X    xwc.x = event.xbutton.x_root - DragX - BorderWidth;
  1145. X    xwc.y = event.xbutton.y_root - DragY - BorderWidth;
  1146. X
  1147. X    if (ConstMove)
  1148. X    {
  1149. X        if (ConstMoveDir == MOVE_HORIZ)
  1150. X        xwc.y = ConstMoveY;
  1151. X
  1152. X        if (ConstMoveDir == MOVE_VERT)
  1153. X        xwc.x = ConstMoveX;
  1154. X
  1155. X        if (ConstMoveDir == MOVE_NONE)
  1156. X        {
  1157. X        xwc.y = ConstMoveY;
  1158. X        xwc.x = ConstMoveX;
  1159. X        }
  1160. X    }
  1161. X    
  1162. X    XFindContext(dpy, DragWindow, TwmContext, &tmp_win);
  1163. X    tmp_win->frame_x = xwc.x;
  1164. X    tmp_win->frame_y = xwc.y;
  1165. X
  1166. X    XConfigureWindow(dpy, DragWindow, xwcm, &xwc);
  1167. X    XRaiseWindow(dpy, DragWindow);
  1168. X    DragWindow = NULL;
  1169. X    ConstMove = FALSE;
  1170. X
  1171. X    enter_flag = TRUE;
  1172. X    client_event.type = ClientMessage;
  1173. X    XSendEvent(dpy, tmp_win->frame, False, 0, &client_event);
  1174. X
  1175. X    return;
  1176. X    }
  1177. X
  1178. X    if (ResizeWindow != NULL)
  1179. X    {
  1180. X    EndResize();
  1181. X    EventHandler[EnterNotify] = HandleEnterNotify;
  1182. X    EventHandler[LeaveNotify] = HandleLeaveNotify;
  1183. X    }
  1184. X
  1185. X    if (w == Root)
  1186. X    {
  1187. X    MenuRoot *tmp;
  1188. X
  1189. X    /*
  1190. X    if (ActiveItem != NULL)
  1191. X    {
  1192. X        int i;
  1193. X
  1194. X        for (i = 0; i < 4; i++)
  1195. X        XFillRectangle(dpy, ActiveItem->w,
  1196. X            MenuXorGC,0,0,1000, 100);
  1197. X
  1198. X        XFlush();
  1199. X    }
  1200. X    */
  1201. X    for (tmp = ActiveMenu; tmp != NULL; tmp = tmp->prev)
  1202. X    {
  1203. X        XUnmapWindow(dpy, tmp->shadow);
  1204. X        XUnmapWindow(dpy, tmp->w);
  1205. X    }
  1206. X    XFlush(dpy);
  1207. X    ActiveMenu = NULL;
  1208. X
  1209. X    if (ActiveItem != NULL)
  1210. X    {
  1211. X        ActiveItem->state = 0;
  1212. X        ExecuteFunction(ActiveItem);
  1213. X        ActiveItem = NULL;
  1214. X        XUngrabPointer(dpy, CurrentTime);
  1215. X    }
  1216. X
  1217. X    return;
  1218. X    }
  1219. X}
  1220. X
  1221. X/***********************************************************************
  1222. X *
  1223. X *  Procedure:
  1224. X *    HandleButtonPress - ButtonPress event handler
  1225. X *
  1226. X ***********************************************************************
  1227. X */
  1228. X
  1229. Xvoid
  1230. XHandleButtonPress()
  1231. X{
  1232. X
  1233. X#ifdef DEBUG
  1234. X    fprintf(stderr, "ButtonPress\n");
  1235. X#endif
  1236. X
  1237. X    XUnmapWindow(dpy, VersionWindow);
  1238. X
  1239. X    if (w == Root)
  1240. X    {
  1241. X    if (Menu[event.xbutton.button] != NULL)
  1242. X    {
  1243. X        XGrabPointer(dpy, Root, True,
  1244. X        ButtonReleaseMask | ButtonMotionMask,
  1245. X        GrabModeAsync, GrabModeSync,
  1246. X        Root, RightArrowCursor, CurrentTime);
  1247. X
  1248. X        PopUpMenu(Menu[event.xbutton.button], 
  1249. X        event.xbutton.x, event.xbutton.y);
  1250. X    }
  1251. X    else if (Item[event.xbutton.button] != NULL)
  1252. X    {
  1253. X        ExecuteFunction(Item[event.xbutton.button]);
  1254. X    }
  1255. X
  1256. X    return;
  1257. X    }
  1258. X
  1259. X    if (tmp_win == NULL)
  1260. X    return;
  1261. X
  1262. X    if (w == tmp_win->frame || w == tmp_win->title_w || w == tmp_win->icon_w)
  1263. X    {
  1264. X    if (w != tmp_win->icon_w)
  1265. X        w = tmp_win->frame;
  1266. X
  1267. X    HandleTitleButton(w, tmp_win, event);
  1268. X
  1269. X    return;
  1270. X    }
  1271. X
  1272. X    if (w == tmp_win->iconify_w)
  1273. X    {
  1274. X    if (!tmp_win->iconified)
  1275. X    {
  1276. X        XWindowChanges xwc;
  1277. X        unsigned int   xwcm;
  1278. X
  1279. X        xwcm = 0;
  1280. X        xwcm |= CWX;
  1281. X        xwcm |= CWY;
  1282. X
  1283. X        if (tmp_win->wmhints && tmp_win->wmhints->flags & IconPositionHint)
  1284. X        {
  1285. X        xwc.x = tmp_win->wmhints->icon_x;
  1286. X        xwc.y = tmp_win->wmhints->icon_y;
  1287. X        }
  1288. X        else
  1289. X        {
  1290. X        xwc.x = event.xbutton.x_root - 5;
  1291. X        xwc.y = event.xbutton.y_root - 5;
  1292. X        }
  1293. X
  1294. X        XConfigureWindow(dpy, tmp_win->icon_w, xwcm, &xwc);
  1295. X        tmp_win->iconified = TRUE;
  1296. X    }
  1297. X
  1298. X    XUnmapWindow(dpy, tmp_win->frame);
  1299. X    XMapSubwindows(dpy, tmp_win->icon_w);
  1300. X    XMapRaised(dpy, tmp_win->icon_w);
  1301. X    if (tmp_win == Focus)
  1302. X    {
  1303. X        XSetInputFocus(dpy, Root, RevertToPointerRoot,
  1304. X        CurrentTime);
  1305. X        Focus = NULL;
  1306. X        FocusRoot = TRUE;
  1307. X    }
  1308. X    return;
  1309. X    }
  1310. X
  1311. X    if (w == tmp_win->resize_w)
  1312. X    {
  1313. X    EventHandler[EnterNotify] = HandleUnknown;
  1314. X    EventHandler[LeaveNotify] = HandleUnknown;
  1315. X    StartResize(event, tmp_win);
  1316. X    }
  1317. X
  1318. X    if (w == tmp_win->focus_w)
  1319. X    {
  1320. X    if (Focus != NULL && Focus != tmp_win)
  1321. X    {
  1322. X        XUnmapWindow(dpy, Focus->hilite_w);
  1323. X    }
  1324. X    XMapWindow(dpy, tmp_win->hilite_w);
  1325. X    XSetInputFocus(dpy, tmp_win->w, RevertToPointerRoot,
  1326. X        CurrentTime);
  1327. X    FocusRoot = FALSE;
  1328. X    Focus = tmp_win;
  1329. X
  1330. X    return;
  1331. X    }
  1332. X}
  1333. X
  1334. X/***********************************************************************
  1335. X *
  1336. X *  Procedure:
  1337. X *    HandleEnterNotify - EnterNotify event handler
  1338. X *
  1339. X ***********************************************************************
  1340. X */
  1341. X
  1342. Xvoid
  1343. XHandleEnterNotify()
  1344. X{
  1345. X    MenuItem *tmp;
  1346. X
  1347. X#ifdef DEBUG
  1348. X    fprintf(stderr, "EnterNotify\n");
  1349. X#endif
  1350. X
  1351. X    if (ActiveMenu == NULL && tmp_win != NULL)
  1352. X    {
  1353. X    if (FocusRoot && tmp_win->mapped)
  1354. X    {
  1355. X        if (Focus != NULL && Focus != tmp_win)
  1356. X        XUnmapWindow(dpy, Focus->hilite_w);
  1357. X
  1358. X        XMapWindow(dpy, tmp_win->hilite_w);
  1359. X        XSetInputFocus(dpy, tmp_win->w, RevertToPointerRoot,
  1360. X            CurrentTime);
  1361. X        Focus = tmp_win;
  1362. X    }
  1363. X    if (enter_flag == FALSE && tmp_win->auto_raise)
  1364. X    {
  1365. X        XEvent client_event;
  1366. X
  1367. X        XRaiseWindow(dpy, tmp_win->frame);
  1368. X        enter_flag = TRUE;
  1369. X        client_event.type = ClientMessage;
  1370. X        XSendEvent(dpy, tmp_win->frame, False, 0, &client_event);
  1371. X    }
  1372. X    return;
  1373. X    }
  1374. X
  1375. X
  1376. X    if (XFindContext(dpy, w, MenuContext, &tmp) != 0)
  1377. X    return;
  1378. X
  1379. X    if (w == tmp->w && tmp->root == ActiveMenu)
  1380. X    {
  1381. X    if (ActiveItem != NULL && ActiveItem->state != 0)
  1382. X    {
  1383. X#ifdef DEBUG
  1384. X        fprintf(stderr, "turning off \"%s\"\n", ActiveItem->item);
  1385. X#endif
  1386. X        XFillRectangle(dpy, ActiveItem->w,MenuXorGC,0,0,1000, 100);
  1387. X        if (tmp->pull != NULL)
  1388. X        XFillRectangle(dpy, ActiveItem->pull, MenuXorGC,0,0,1000, 100);
  1389. X        ActiveItem->state = 0;
  1390. X    }
  1391. X
  1392. X    if (tmp->state == 0)
  1393. X    {
  1394. X#ifdef DEBUG
  1395. X        fprintf(stderr, "turning on \"%s\"\n", tmp->item);
  1396. X#endif
  1397. X        XFillRectangle(dpy, tmp->w,MenuXorGC,0,0,1000, 100);
  1398. X        if (tmp->pull)
  1399. X        XFillRectangle(dpy, tmp->pull, MenuXorGC,0,0,1000, 100);
  1400. X        tmp->state = 1;
  1401. X    }
  1402. X    ActiveItem = tmp;
  1403. X
  1404. X    return;
  1405. X    }
  1406. X
  1407. X    if (w == tmp->pull && tmp->root == ActiveMenu)
  1408. X    {
  1409. X    XGrabServer(dpy);
  1410. X    PopUpMenu(tmp->sub, event.xcrossing.x_root,
  1411. X        event.xcrossing.y_root);
  1412. X    XUngrabServer(dpy);
  1413. X
  1414. X    return;
  1415. X    }
  1416. X}
  1417. X
  1418. X/***********************************************************************
  1419. X *
  1420. X *  Procedure:
  1421. X *    HandleLeaveNotify - LeaveNotify event handler
  1422. X *
  1423. X ***********************************************************************
  1424. X */
  1425. X
  1426. Xvoid
  1427. XHandleLeaveNotify()
  1428. X{
  1429. X    MenuItem *tmp;
  1430. X
  1431. X#ifdef DEBUG
  1432. X    fprintf(stderr, "LeaveNotify\n");
  1433. X#endif
  1434. X    if (tmp_win != NULL)
  1435. X    {
  1436. X    XUnmapWindow(dpy, VersionWindow);
  1437. X    if (FocusRoot)
  1438. X    {
  1439. X        if (event.xcrossing.detail != NotifyInferior)
  1440. X        {
  1441. X        XUnmapWindow(dpy, tmp_win->hilite_w);
  1442. X        XSetInputFocus(dpy, Root, RevertToPointerRoot,
  1443. X            CurrentTime);
  1444. X        Focus = NULL;
  1445. X        }
  1446. X    }
  1447. X    return;
  1448. X    }
  1449. X
  1450. X    if (XFindContext(dpy, w, MenuContext, &tmp) != 0)
  1451. X    return;
  1452. X
  1453. X    if (w == tmp->root->w)
  1454. X    {
  1455. X    int rootx, rooty, x, y;
  1456. X    int wx, wy, ww, wh;
  1457. X
  1458. X    /* see if the mouse really left the window
  1459. X     * or just crossed into a sub-window
  1460. X     */
  1461. X
  1462. X    XQueryPointer(dpy, w, &JunkRoot,
  1463. X        &JunkChild, &rootx, &rooty, &x, &y, &JunkMask);
  1464. X
  1465. X    XGetGeometry(dpy, w, &JunkRoot, &wx, &wy,
  1466. X        &ww, &wh, &JunkBW,
  1467. X        &JunkDepth);
  1468. X    
  1469. X    if (rootx < wx ||
  1470. X        rootx > (wx + ww) ||
  1471. X        rooty < wy ||
  1472. X        rooty > (wy + wh))
  1473. X    {
  1474. X        ActiveItem = NULL;
  1475. X        if (tmp->root->prev != NULL)
  1476. X        {
  1477. X        if (ActiveMenu == tmp->root)
  1478. X        {
  1479. X            XUnmapWindow(dpy, ActiveMenu->shadow);
  1480. X            XUnmapWindow(dpy, ActiveMenu->w);
  1481. X            ActiveMenu = tmp->root->prev;
  1482. X        }
  1483. X        }
  1484. X    }
  1485. X    return;
  1486. X    }
  1487. X
  1488. X    if (w == tmp->w);
  1489. X    {
  1490. X    if (tmp == ActiveItem)
  1491. X        ActiveItem = NULL;
  1492. X
  1493. X    if (tmp->state != 0)
  1494. X    {
  1495. X#ifdef DEBUG
  1496. X        fprintf(stderr, "turning off \"%s\"\n", tmp->item);
  1497. X#endif
  1498. X        XFillRectangle(dpy, tmp->w,MenuXorGC,0,0,1000, 100);
  1499. X        if (tmp->pull != NULL)
  1500. X        XFillRectangle(dpy, tmp->pull, MenuXorGC,0,0,1000, 100);
  1501. X        tmp->state = 0;
  1502. X    }
  1503. X
  1504. X    return;
  1505. X    }
  1506. X}
  1507. X
  1508. X/***********************************************************************
  1509. X *
  1510. X *  Procedure:
  1511. X *    HandleConfigureNotify - ConfigureNotify event handler
  1512. X *
  1513. X ***********************************************************************
  1514. X */
  1515. X
  1516. Xvoid
  1517. XHandleConfigureNotify()
  1518. X{
  1519. X#ifdef DEBUG
  1520. X    fprintf(stderr, "ConfigureNotify\n");
  1521. X#endif
  1522. X    if (tmp_win == NULL)
  1523. X    return;
  1524. X
  1525. X    if (event.xconfigure.override_redirect)
  1526. X    return;
  1527. X
  1528. X    SetupWindow(tmp_win,
  1529. X    tmp_win->frame_x + event.xconfigure.x,
  1530. X    tmp_win->frame_y + event.xconfigure.y - TITLE_BAR_HEIGHT - BorderWidth,
  1531. X    event.xconfigure.width,
  1532. X    event.xconfigure.height + TITLE_BAR_HEIGHT + BorderWidth);
  1533. X}
  1534. X
  1535. X/***********************************************************************
  1536. X *
  1537. X *  Procedure:
  1538. X *    HandleUnknown - unknown event handler
  1539. X *
  1540. X ***********************************************************************
  1541. X */
  1542. X
  1543. Xvoid
  1544. XHandleUnknown()
  1545. X{
  1546. X#ifdef DEBUG
  1547. X    fprintf(stderr, "type = %d\n", event.type);
  1548. X#endif
  1549. X}
  1550. X
  1551. X/***********************************************************************
  1552. X *
  1553. X *  Procedure:
  1554. X *    HandleTitleButton - handle a button press event in the title bar
  1555. X *
  1556. X *  Inputs:
  1557. X *    w    - the window effected by the button press
  1558. X *    tmp_win    - the TwmWindow structure
  1559. X *    event    - the X event structure for the button press
  1560. X *
  1561. X ***********************************************************************
  1562. X */
  1563. X
  1564. XHandleTitleButton(w, tmp_win, event)
  1565. XWindow w;
  1566. XTwmWindow *tmp_win ;
  1567. XXEvent event;
  1568. X{
  1569. X    static Time last_time = 0;
  1570. X
  1571. X    if (event.xbutton.button > MAX_BUTTONS)
  1572. X    return;
  1573. X
  1574. X    switch (TitleButton[event.xbutton.button])
  1575. X    {
  1576. X    case T_NOP:
  1577. X    break;
  1578. X     
  1579. X    case T_RAISE:
  1580. X    if (w == tmp_win->icon_w)
  1581. X    {
  1582. X        XUnmapWindow(dpy, tmp_win->icon_w);
  1583. X        XMapWindow(dpy, tmp_win->w);
  1584. X        XMapRaised(dpy, tmp_win->frame);
  1585. X        if (WarpCursor)
  1586. X        {
  1587. X        XWarpPointer(dpy, None, tmp_win->frame,
  1588. X            0, 0, 0, 0, 30, 8);
  1589. X        }
  1590. X        tmp_win->icon = FALSE;
  1591. X    }
  1592. X    else
  1593. X        XRaiseWindow(dpy, tmp_win->frame);
  1594. X    break;
  1595. X
  1596. X    case T_LOWER:
  1597. X    XLowerWindow(dpy, w);
  1598. X    break;
  1599. X
  1600. X    case T_MOVE:
  1601. X    EventHandler[EnterNotify] = HandleUnknown;
  1602. X    EventHandler[LeaveNotify] = HandleUnknown;
  1603. X    XGrabServer(dpy);
  1604. X    XGrabPointer(dpy, event.xbutton.root, True,
  1605. X        ButtonReleaseMask | ButtonMotionMask,
  1606. X        GrabModeAsync, GrabModeSync,
  1607. X        Root, MoveCursor, CurrentTime);
  1608. X
  1609. X    DragWindow = w;
  1610. X
  1611. X    DragX = event.xbutton.x;
  1612. X    DragY = event.xbutton.y;
  1613. X
  1614. X    XGetGeometry(dpy, w, &JunkRoot, &JunkX, &JunkY,
  1615. X        &DragWidth, &DragHeight, &JunkBW,
  1616. X        &JunkDepth);
  1617. X
  1618. X    MoveOutline((Window)event.xbutton.root,
  1619. X        event.xbutton.x_root-DragX-BorderWidth,
  1620. X        event.xbutton.y_root-DragY-BorderWidth,
  1621. X        DragWidth + 2 * BorderWidth,
  1622. X        DragHeight + 2 * BorderWidth);
  1623. X
  1624. X    if ((event.xbutton.time - last_time) < 400)
  1625. X    {
  1626. X        int width, height;
  1627. X
  1628. X        ConstMove = TRUE;
  1629. X        ConstMoveDir = MOVE_NONE;
  1630. X        ConstMoveX = event.xbutton.x_root - DragX - BorderWidth;
  1631. X        ConstMoveY = event.xbutton.y_root - DragY - BorderWidth;
  1632. X        width = DragWidth + 2 * BorderWidth;
  1633. X        height = DragHeight + 2 * BorderWidth;
  1634. X        ConstMoveXL = ConstMoveX + width/3;
  1635. X        ConstMoveXR = ConstMoveX + 2*(width/3);
  1636. X        ConstMoveYT = ConstMoveY + height/3;
  1637. X        ConstMoveYB = ConstMoveY + 2*(height/3);
  1638. X
  1639. X        XWarpPointer(dpy, None, w,
  1640. X        0, 0, 0, 0, DragWidth/2, DragHeight/2);
  1641. X
  1642. X        XQueryPointer(dpy, DragWindow, &JunkRoot, &JunkChild,
  1643. X        &JunkX, &JunkY, &DragX, &DragY, &JunkMask);
  1644. X    }
  1645. X    last_time = event.xbutton.time;
  1646. X    break;
  1647. X
  1648. X    }
  1649. X}
  1650. SHAR_EOF
  1651. if test 23151 -ne "`wc -c < events.c`"
  1652. then
  1653.     echo shar: error transmitting "events.c" '(should have been 23151 characters)'
  1654. fi
  1655. fi
  1656. if test -f 'resize.c'
  1657. then
  1658.     echo shar: will not over-write existing file "resize.c"
  1659. else
  1660. echo extracting "resize.c"
  1661. sed 's/^X//' >resize.c <<'SHAR_EOF'
  1662. X/*****************************************************************************/
  1663. X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
  1664. X/**                          Salt Lake City, Utah                           **/
  1665. X/**                                                                         **/
  1666. X/**                           All Rights Reserved                           **/
  1667. X/**                                                                         **/
  1668. X/**    Permission to use, copy, modify, and distribute this software and    **/
  1669. X/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
  1670. X/**    granted, provided that the above copyright notice appear  in  all    **/
  1671. X/**    copies and that both  that  copyright  notice  and  this  permis-    **/
  1672. X/**    sion  notice appear in supporting  documentation,  and  that  the    **/
  1673. X/**    name  of Evans & Sutherland  not be used in advertising or publi-    **/
  1674. X/**    city pertaining to distribution  of the software without  specif-    **/
  1675. X/**    ic, written prior permission.                                        **/
  1676. X/**                                                                         **/
  1677. X/**    EVANS  & SUTHERLAND  DISCLAIMS  ALL  WARRANTIES  WITH  REGARD  TO    **/
  1678. X/**    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI-    **/
  1679. X/**    TY AND FITNESS, IN NO EVENT SHALL EVANS &  SUTHERLAND  BE  LIABLE    **/
  1680. X/**    FOR  ANY  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY  DAM-    **/
  1681. X/**    AGES  WHATSOEVER RESULTING FROM  LOSS OF USE,  DATA  OR  PROFITS,    **/
  1682. X/**    WHETHER   IN  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS    **/
  1683. X/**    ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE  OR PER-    **/
  1684. X/**    FORMANCE OF THIS SOFTWARE.                                           **/
  1685. X/*****************************************************************************/
  1686. X
  1687. X/***********************************************************************
  1688. X *
  1689. X * $Header: resize.c,v 1.6 88/04/15 07:09:35 tlastran Exp $
  1690. X *
  1691. X * window resizing borrowed from the "wm" window manager
  1692. X *
  1693. X * 11-Dec-87 Thomas E. LaStrange        File created
  1694. X *
  1695. X ***********************************************************************/
  1696. X
  1697. X#ifndef lint
  1698. Xstatic char RCSinfo[]=
  1699. X"$Header: resize.c,v 1.6 88/04/15 07:09:35 tlastran Exp $";
  1700. X#endif
  1701. X
  1702. X#include <stdio.h>
  1703. X#include "twm.h"
  1704. X#include "util.h"
  1705. X#include "resize.h"
  1706. X#include "resize.bm"
  1707. X#include "focus.bm"
  1708. X
  1709. X#define MINHEIGHT 32
  1710. X#define MINWIDTH 60
  1711. X
  1712. Xstatic int dragx;    /* all these variables are used */
  1713. Xstatic int dragy;    /* in resize operations */
  1714. Xstatic int dragWidth;
  1715. Xstatic int dragHeight;
  1716. X
  1717. Xstatic int origx;
  1718. Xstatic int origy;
  1719. Xstatic int origWidth;
  1720. Xstatic int origHeight;
  1721. X
  1722. Xstatic int clampTop;
  1723. Xstatic int clampBottom;
  1724. Xstatic int clampLeft;
  1725. Xstatic int clampRight;
  1726. X
  1727. X/***********************************************************************
  1728. X *
  1729. X *  Procedure:
  1730. X *    StartResize - begin a window resize operation
  1731. X *
  1732. X *  Inputs:
  1733. X *    ev    - the event structure (button press)
  1734. X *    tmp_win    - the TwmWindow pointer
  1735. X *
  1736. X ***********************************************************************
  1737. X */
  1738. X
  1739. Xvoid
  1740. XStartResize(ev, tmp_win)
  1741. XXEvent ev;
  1742. XTwmWindow *tmp_win;
  1743. X{
  1744. X    Window      junkRoot;
  1745. X    int         junkbw, junkDepth;
  1746. X
  1747. X    XMapRaised(dpy, SizeWindow);
  1748. X    ResizeWindow = tmp_win->frame;
  1749. X    XGrabServer(dpy);
  1750. X    XGrabPointer(dpy, ev.xbutton.root, True,
  1751. X    ButtonReleaseMask | PointerMotionMask,
  1752. X    GrabModeAsync, GrabModeSync,
  1753. X    Root, MoveCursor, CurrentTime);
  1754. X
  1755. X    XGetGeometry(dpy, (Drawable) tmp_win->frame, &junkRoot,
  1756. X    &dragx, &dragy, &dragWidth, &dragHeight, &junkbw,
  1757. X         &junkDepth);
  1758. X    dragx += BorderWidth;
  1759. X    dragy += BorderWidth;
  1760. X    origx = dragx;
  1761. X    origy = dragy;
  1762. X    origWidth = dragWidth;
  1763. X    origHeight = dragHeight;
  1764. X    clampTop = clampBottom = clampLeft = clampRight = 0;
  1765. X
  1766. X    DisplaySize(tmp_win, origWidth, origHeight);
  1767. X}
  1768. X
  1769. X/***********************************************************************
  1770. X *
  1771. X *  Procedure:
  1772. X *    DoResize - move the rubberband around.  This is called for
  1773. X *           each motion event when we are resizing 
  1774. X *
  1775. X *  Inputs:
  1776. X *    ev    - the event structure for the motion event
  1777. X *    tmp_win    - the current twm window
  1778. X *
  1779. X ***********************************************************************
  1780. X */
  1781. X
  1782. Xvoid
  1783. XDoResize(ev, tmp_win)
  1784. XXEvent ev;
  1785. XTwmWindow *tmp_win;
  1786. X{
  1787. X    int action;
  1788. X
  1789. X    action = 0;
  1790. X
  1791. X    if (clampTop) {
  1792. X    int         delta = ev.xmotion.y_root - dragy;
  1793. X    if (dragHeight - delta < MINHEIGHT) {
  1794. X        delta = dragHeight - MINHEIGHT;
  1795. X        clampTop = 0;
  1796. X    }
  1797. X    dragy += delta;
  1798. X    dragHeight -= delta;
  1799. X    action = 1;
  1800. X    }
  1801. X    else if (ev.xmotion.y_root <= dragy/* ||
  1802. X         ev.xmotion.y_root == findRootInfo(root)->rooty*/) {
  1803. X    dragy = ev.xmotion.y_root;
  1804. X    dragHeight = origy + origHeight -
  1805. X        ev.xmotion.y_root;
  1806. X    clampBottom = 0;
  1807. X    clampTop = 1;
  1808. X    action = 1;
  1809. X    }
  1810. X    if (clampLeft) {
  1811. X    int         delta = ev.xmotion.x_root - dragx;
  1812. X    if (dragWidth - delta < MINWIDTH) {
  1813. X        delta = dragWidth - MINWIDTH;
  1814. X        clampLeft = 0;
  1815. X    }
  1816. X    dragx += delta;
  1817. X    dragWidth -= delta;
  1818. X    action = 1;
  1819. X    }
  1820. X    else if (ev.xmotion.x_root <= dragx/* ||
  1821. X         ev.xmotion.x_root == findRootInfo(root)->rootx*/) {
  1822. X    dragx = ev.xmotion.x_root;
  1823. X    dragWidth = origx + origWidth -
  1824. X        ev.xmotion.x_root;
  1825. X    clampRight = 0;
  1826. X    clampLeft = 1;
  1827. X    action = 1;
  1828. X    }
  1829. X    if (clampBottom) {
  1830. X    int         delta = ev.xmotion.y_root - dragy - dragHeight;
  1831. X    if (dragHeight + delta < MINHEIGHT) {
  1832. X        delta = MINHEIGHT - dragHeight;
  1833. X        clampBottom = 0;
  1834. X    }
  1835. X    dragHeight += delta;
  1836. X    action = 1;
  1837. X    }
  1838. X    else if (ev.xmotion.y_root >= dragy + dragHeight - 1/* ||
  1839. X       ev.xmotion.y_root == findRootInfo(root)->rooty
  1840. X       + findRootInfo(root)->rootheight - 1*/) {
  1841. X    dragy = origy;
  1842. X    dragHeight = 1 + ev.xmotion.y_root - dragy;
  1843. X    clampTop = 0;
  1844. X    clampBottom = 1;
  1845. X    action = 1;
  1846. X    }
  1847. X    if (clampRight) {
  1848. X    int         delta = ev.xmotion.x_root - dragx - dragWidth;
  1849. X    if (dragWidth + delta < MINWIDTH) {
  1850. X        delta = MINWIDTH - dragWidth;
  1851. X        clampRight = 0;
  1852. X    }
  1853. X    dragWidth += delta;
  1854. X    action = 1;
  1855. X    }
  1856. X    else if (ev.xmotion.x_root >= dragx + dragWidth - 1/* ||
  1857. X         ev.xmotion.x_root == findRootInfo(root)->rootx +
  1858. X         findRootInfo(root)->rootwidth - 1*/) {
  1859. X    dragx = origx;
  1860. X    dragWidth = 1 + ev.xmotion.x_root - origx;
  1861. X    clampLeft = 0;
  1862. X    clampRight = 1;
  1863. X    action = 1;
  1864. X    }
  1865. X    if (action) {
  1866. X    MoveOutline(Root,
  1867. X            dragx - BorderWidth,
  1868. X            dragy - BorderWidth,
  1869. X            dragWidth + 2 * BorderWidth,
  1870. X            dragHeight + 2 * BorderWidth);
  1871. X    }
  1872. X
  1873. X    DisplaySize(tmp_win, dragWidth, dragHeight);
  1874. X}
  1875. X
  1876. X/***********************************************************************
  1877. X *
  1878. X *  Procedure:
  1879. X *    DisplaySize - display the size in the dimensions window
  1880. X *
  1881. X *  Inputs:
  1882. X *    tmp_win - the current twm window 
  1883. X *    width    - the width of the rubber band
  1884. X *    height    - the height of the rubber band
  1885. X *
  1886. X ***********************************************************************
  1887. X */
  1888. X
  1889. Xvoid
  1890. XDisplaySize(tmp_win, width, height)
  1891. XTwmWindow *tmp_win;
  1892. Xint width;
  1893. Xint height;
  1894. X{
  1895. X    char str[100];
  1896. X    int dwidth;
  1897. X    int dheight;
  1898. X
  1899. X    dwidth = width;
  1900. X    dheight = height - tmp_win->title_height;
  1901. X
  1902. X    if (tmp_win->hints.flags&PMinSize && tmp_win->hints.flags & PResizeInc)
  1903. X    {
  1904. X    dwidth -= tmp_win->hints.min_width;
  1905. X    dheight -= tmp_win->hints.min_height;
  1906. X    }
  1907. X
  1908. X    if (tmp_win->hints.flags & PResizeInc)
  1909. X    {
  1910. X    dwidth /= tmp_win->hints.width_inc;
  1911. X    dheight /= tmp_win->hints.height_inc;
  1912. X    }
  1913. X
  1914. X    sprintf(str, "%d x %d", dwidth, dheight);
  1915. X
  1916. X    width = XTextWidth(SizeFont, str, strlen(str)) + 20,
  1917. X    strcat(str, "        ");
  1918. X    XResizeWindow(dpy, SizeWindow, width, SizeFontHeight + 4);
  1919. X    XRaiseWindow(dpy, SizeWindow);
  1920. X    XDrawImageString(dpy, SizeWindow, SizeNormalGC,
  1921. X    10, 2 + SizeFont->ascent, str, strlen(str));
  1922. X}
  1923. X
  1924. X/***********************************************************************
  1925. X *
  1926. X *  Procedure:
  1927. X *    EndResize - finish the resize operation
  1928. X *
  1929. X ***********************************************************************
  1930. X */
  1931. X
  1932. Xvoid
  1933. XEndResize()
  1934. X{
  1935. X    TwmWindow *tmp_win;
  1936. X
  1937. X    XUnmapWindow(dpy, SizeWindow);
  1938. X    MoveOutline(Root, 0, 0, 0, 0);
  1939. X
  1940. X    XFindContext(dpy, ResizeWindow, TwmContext, &tmp_win);
  1941. X
  1942. X    dragHeight = dragHeight - tmp_win->title_height;
  1943. X
  1944. X    if (tmp_win->hints.flags&PMinSize && tmp_win->hints.flags & PResizeInc)
  1945. X    {
  1946. X    dragWidth -= tmp_win->hints.min_width;
  1947. X    dragHeight -= tmp_win->hints.min_height;
  1948. X    }
  1949. X
  1950. X    if (tmp_win->hints.flags & PResizeInc)
  1951. X    {
  1952. X    dragWidth /= tmp_win->hints.width_inc;
  1953. X    dragHeight /= tmp_win->hints.height_inc;
  1954. X
  1955. X    dragWidth *= tmp_win->hints.width_inc;
  1956. X    dragHeight *= tmp_win->hints.height_inc;
  1957. X    }
  1958. X
  1959. X    if (tmp_win->hints.flags&PMinSize && tmp_win->hints.flags & PResizeInc)
  1960. X    {
  1961. X    dragWidth += tmp_win->hints.min_width;
  1962. X    dragHeight += tmp_win->hints.min_height;
  1963. X    }
  1964. X
  1965. X    dragHeight = dragHeight + tmp_win->title_height;
  1966. X
  1967. X    SetupWindow(tmp_win,
  1968. X    dragx - BorderWidth,
  1969. X    dragy - BorderWidth,
  1970. X    dragWidth, dragHeight);
  1971. X
  1972. X    XRaiseWindow(dpy, ResizeWindow);
  1973. X    ResizeWindow = NULL;
  1974. X}
  1975. X
  1976. X/***********************************************************************
  1977. X *
  1978. X *  Procedure:
  1979. X *    SetupWindow - set window sizes, this was called from either
  1980. X *        AddWindow, EndResize, or HandleConfigureNotify.
  1981. X *
  1982. X *  Inputs:
  1983. X *    tmp_win    - the TwmWindow pointer
  1984. X *    x    - the x coordinate of the frame window
  1985. X *    y    - the y coordinate of the frame window
  1986. X *    w    - the width of the frame window
  1987. X *    h    - the height of the frame window
  1988. X *
  1989. X ***********************************************************************
  1990. X */
  1991. X
  1992. Xvoid
  1993. XSetupWindow(tmp_win, x, y, w, h)
  1994. XTwmWindow *tmp_win;
  1995. Xint x, y, w, h;
  1996. X{
  1997. X    XWindowChanges xwc;
  1998. X    unsigned int   xwcm;
  1999. X    int width;
  2000. X
  2001. X    tmp_win->frame_x = x;
  2002. X    tmp_win->frame_y = y;
  2003. X
  2004. X    xwcm = CWX | CWY | CWWidth | CWHeight;
  2005. X
  2006. X    xwc.x = x;
  2007. X    xwc.y = y;
  2008. X    xwc.width = w;
  2009. X    xwc.height = h;
  2010. X    XConfigureWindow(dpy, tmp_win->frame, xwcm, &xwc);
  2011. X
  2012. X    xwcm = CWWidth;
  2013. X    XConfigureWindow(dpy, tmp_win->title_w, xwcm, &xwc);
  2014. X
  2015. X    xwcm |= CWX | CWY | CWHeight;
  2016. X    xwc.x = 0;
  2017. X    xwc.y = tmp_win->title_height;
  2018. X    xwc.height = h - tmp_win->title_height;
  2019. X    XConfigureWindow(dpy, tmp_win->w, xwcm, &xwc);
  2020. X
  2021. X    xwcm = CWX;
  2022. X    xwc.x = w - resize_width - 1;
  2023. X    XConfigureWindow(dpy, tmp_win->resize_w, xwcm, &xwc);
  2024. X
  2025. X    xwc.x = w - resize_width - focus_width - 3;
  2026. X    XConfigureWindow(dpy, tmp_win->focus_w, xwcm, &xwc);
  2027. X
  2028. X    width = w - TitleBarX - focus_width - resize_width - 5 -
  2029. X    tmp_win->name_width - 10;
  2030. X
  2031. X    if (width <= 0)
  2032. X    {
  2033. X    xwc.x = 3000;
  2034. X    xwc.width = 1;
  2035. X    }
  2036. X    else
  2037. X    {
  2038. X    xwc.x = TitleBarX + tmp_win->name_width + 6;
  2039. X    xwc.width = width;
  2040. X    }
  2041. X
  2042. X    xwcm = CWX | CWWidth;
  2043. X    XConfigureWindow(dpy, tmp_win->hilite_w, xwcm, &xwc);
  2044. X}
  2045. SHAR_EOF
  2046. if test 10581 -ne "`wc -c < resize.c`"
  2047. then
  2048.     echo shar: error transmitting "resize.c" '(should have been 10581 characters)'
  2049. fi
  2050. fi
  2051. if test -f 'util.c'
  2052. then
  2053.     echo shar: will not over-write existing file "util.c"
  2054. else
  2055. echo extracting "util.c"
  2056. sed 's/^X//' >util.c <<'SHAR_EOF'
  2057. X/*****************************************************************************/
  2058. X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
  2059. X/**                          Salt Lake City, Utah                           **/
  2060. X/**                                                                         **/
  2061. X/**                           All Rights Reserved                           **/
  2062. X/**                                                                         **/
  2063. X/**    Permission to use, copy, modify, and distribute this software and    **/
  2064. X/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
  2065. X/**    granted, provided that the above copyright notice appear  in  all    **/
  2066. X/**    copies and that both  that  copyright  notice  and  this  permis-    **/
  2067. X/**    sion  notice appear in supporting  documentation,  and  that  the    **/
  2068. X/**    name  of Evans & Sutherland  not be used in advertising or publi-    **/
  2069. X/**    city pertaining to distribution  of the software without  specif-    **/
  2070. X/**    ic, written prior permission.                                        **/
  2071. X/**                                                                         **/
  2072. X/**    EVANS  & SUTHERLAND  DISCLAIMS  ALL  WARRANTIES  WITH  REGARD  TO    **/
  2073. X/**    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI-    **/
  2074. X/**    TY AND FITNESS, IN NO EVENT SHALL EVANS &  SUTHERLAND  BE  LIABLE    **/
  2075. X/**    FOR  ANY  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY  DAM-    **/
  2076. X/**    AGES  WHATSOEVER RESULTING FROM  LOSS OF USE,  DATA  OR  PROFITS,    **/
  2077. X/**    WHETHER   IN  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS    **/
  2078. X/**    ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE  OR PER-    **/
  2079. X/**    FORMANCE OF THIS SOFTWARE.                                           **/
  2080. X/*****************************************************************************/
  2081. X
  2082. X/***********************************************************************
  2083. X *
  2084. X * $Header: util.c,v 1.10 88/04/15 07:09:43 tlastran Exp $
  2085. X *
  2086. X * utility routines for twm
  2087. X *
  2088. X * 28-Oct-87 Thomas E. LaStrange    File created
  2089. X *
  2090. X ***********************************************************************/
  2091. X
  2092. X#ifndef lint
  2093. Xstatic char RCSinfo[]=
  2094. X"$Header: util.c,v 1.10 88/04/15 07:09:43 tlastran Exp $";
  2095. X#endif
  2096. X
  2097. X#include <stdio.h>
  2098. X#include "twm.h"
  2099. X#include "gram.h"
  2100. X
  2101. X/***********************************************************************
  2102. X *
  2103. X *  Procedure:
  2104. X *    InitButtons - initialize the title bar buttons
  2105. X *
  2106. X ***********************************************************************
  2107. X */
  2108. X
  2109. Xvoid
  2110. XInitButtons()
  2111. X{
  2112. X    int i;
  2113. X
  2114. X    for (i = 0; i < (MAX_BUTTONS + 1); i++)
  2115. X    TitleButton[i] = T_NOP;
  2116. X
  2117. X    TitleButton[1] = T_RAISE;
  2118. X    TitleButton[2] = T_MOVE;
  2119. X    TitleButton[3] = T_LOWER;
  2120. X}
  2121. X
  2122. X/***********************************************************************
  2123. X *
  2124. X *  Procedure:
  2125. X *    MoveOutline - move a window outline
  2126. X *
  2127. X *  Inputs:
  2128. X *    root        - the window we are outlining
  2129. X *    x        - upper left x coordinate
  2130. X *    y        - upper left y coordinate
  2131. X *    width        - the width of the rectangle
  2132. X *    height        - the height of the rectangle
  2133. X *
  2134. X ***********************************************************************
  2135. X */
  2136. X
  2137. Xvoid
  2138. XMoveOutline(root, x, y, width, height)
  2139. X    Window root;
  2140. X    int x, y, width, height;
  2141. X{
  2142. X    static int    lastx = 0;
  2143. X    static int    lasty = 0;
  2144. X    static int    lastWidth = 0;
  2145. X    static int    lastHeight = 0;
  2146. X    int        xl, xr, yt, yb;
  2147. X    int        xthird, ythird;
  2148. X    XSegment    outline[16];
  2149. X    XSegment    *r = outline;
  2150. X
  2151. X    if (x == lastx && y == lasty && width == lastWidth && height == lastHeight)
  2152. X    return;
  2153. X    
  2154. X    xthird = lastWidth/3;
  2155. X    ythird = lastHeight/3;
  2156. X    xl = lastx;
  2157. X    xr = lastx + lastWidth - 1;
  2158. X    yt = lasty;
  2159. X    yb = lasty + lastHeight - 1;
  2160. X
  2161. X    if (lastWidth || lastHeight)
  2162. X    {
  2163. X    r->x1 = xl;
  2164. X    r->y1 = yt;
  2165. X    r->x2 = xr;
  2166. X    r++->y2 = yt;
  2167. X
  2168. X    r->x1 = xl;
  2169. X    r->y1 = yb;
  2170. X    r->x2 = xr;
  2171. X    r++->y2 = yb;
  2172. X
  2173. X    r->x1 = xl;
  2174. X    r->y1 = yt;
  2175. X    r->x2 = xl;
  2176. X    r++->y2 = yb;
  2177. X
  2178. X    r->x1 = xr;
  2179. X    r->y1 = yt;
  2180. X    r->x2 = xr;
  2181. X    r++->y2 = yb;
  2182. X
  2183. X    r->x1 = xl + xthird;
  2184. X    r->y1 = yt;
  2185. X    r->x2 = r->x1;
  2186. X    r++->y2 = yb;
  2187. X
  2188. X    r->x1 = xl + (2 * xthird);
  2189. X    r->y1 = yt;
  2190. X    r->x2 = r->x1;
  2191. X    r++->y2 = yb;
  2192. X
  2193. X    r->x1 = xl;
  2194. X    r->y1 = yt + ythird;
  2195. X    r->x2 = xr;
  2196. X    r->y2 = r->y1;
  2197. X    r++;
  2198. X
  2199. X    r->x1 = xl;
  2200. X    r->y1 = yt + (2 * ythird);
  2201. X    r->x2 = xr;
  2202. X    r->y2 = r->y1;
  2203. X    r++;
  2204. X    }
  2205. X
  2206. X    lastx = x;
  2207. X    lasty = y;
  2208. X    lastWidth = width;
  2209. X    lastHeight = height;
  2210. X    xthird = lastWidth/3;
  2211. X    ythird = lastHeight/3;
  2212. X    xl = lastx;
  2213. X    xr = lastx + lastWidth - 1;
  2214. X    yt = lasty;
  2215. X    yb = lasty + lastHeight - 1;
  2216. X
  2217. X    if (lastWidth || lastHeight)
  2218. X    {
  2219. X    r->x1 = xl;
  2220. X    r->y1 = yt;
  2221. X    r->x2 = xr;
  2222. X    r++->y2 = yt;
  2223. X
  2224. X    r->x1 = xl;
  2225. X    r->y1 = yb;
  2226. X    r->x2 = xr;
  2227. X    r++->y2 = yb;
  2228. X
  2229. X    r->x1 = xl;
  2230. X    r->y1 = yt;
  2231. X    r->x2 = xl;
  2232. X    r++->y2 = yb;
  2233. X
  2234. X    r->x1 = xr;
  2235. X    r->y1 = yt;
  2236. X    r->x2 = xr;
  2237. X    r++->y2 = yb;
  2238. X
  2239. X    r->x1 = xl + xthird;
  2240. X    r->y1 = yt;
  2241. X    r->x2 = r->x1;
  2242. X    r++->y2 = yb;
  2243. X
  2244. X    r->x1 = xl + (2 * xthird);
  2245. X    r->y1 = yt;
  2246. X    r->x2 = r->x1;
  2247. X    r++->y2 = yb;
  2248. X
  2249. X    r->x1 = xl;
  2250. X    r->y1 = yt + ythird;
  2251. X    r->x2 = xr;
  2252. X    r->y2 = r->y1;
  2253. X    r++;
  2254. X
  2255. X    r->x1 = xl;
  2256. X    r->y1 = yt + (2 * ythird);
  2257. X    r->x2 = xr;
  2258. X    r->y2 = r->y1;
  2259. X    r++;
  2260. X    }
  2261. X    if (r != outline)
  2262. X    {
  2263. X    XDrawSegments(dpy, root, DrawGC, outline, r - outline);
  2264. X    }
  2265. X}
  2266. X
  2267. X/***********************************************************************
  2268. X *
  2269. X *  Procedure:
  2270. X *    MakePixmap - make a pixmap
  2271. X *
  2272. X *  Returned Value:
  2273. X *    pid    - the pixmap id
  2274. X *
  2275. X *  Inputs:
  2276. X *    w    - the window to associate the pixmap with
  2277. X *    gc    - the graphics context to use
  2278. X *    data    - pointer to the pixmap data
  2279. X *    width    - the width of the pixmap
  2280. X *    height    - the height of the pixmap
  2281. X *
  2282. X ***********************************************************************
  2283. X */
  2284. X
  2285. XPixmap
  2286. XMakePixmap(w, gc, data, width, height)
  2287. X    Drawable w;
  2288. X    GC gc;
  2289. X    short *data;
  2290. X    int width, height;
  2291. X{
  2292. X    XImage ximage;
  2293. X    Pixmap pid;
  2294. X
  2295. X    pid = XCreatePixmap(dpy, w, width, height, DefaultDepth(dpy, 0));
  2296. X
  2297. X    ximage.height = height;
  2298. X    ximage.width = width;
  2299. X    ximage.xoffset = 0;
  2300. X    ximage.format = XYBitmap;
  2301. X    ximage.data = (char *) data;
  2302. X    ximage.byte_order = LSBFirst;
  2303. X    ximage.bitmap_unit = 16;
  2304. X    ximage.bitmap_bit_order = LSBFirst;
  2305. X    ximage.bitmap_pad = 16;
  2306. X    ximage.bytes_per_line = (width + 15) / 16 * 2;
  2307. X    ximage.depth = 1;
  2308. X
  2309. X    XPutImage(dpy, pid, gc, &ximage, 0, 0, 0, 0, width, height);
  2310. X    return (pid);
  2311. X}
  2312. X
  2313. XGetUnknownIcon(name)
  2314. Xchar *name;
  2315. X{
  2316. X    int status, junk_hotx, junk_hoty;
  2317. X
  2318. X    status = XReadBitmapFile(dpy, Root, name, &UnknownWidth,
  2319. X    &UnknownHeight, &UnknownPm, &junk_hotx, &junk_hoty);
  2320. X
  2321. X    switch(status)
  2322. X    {
  2323. X    case BitmapSuccess:
  2324. X        break;
  2325. X
  2326. X    case BitmapFileInvalid:
  2327. X        fprintf(stderr, ".twmrc: invalid bitmap file\n");
  2328. X        break;
  2329. X
  2330. X    case BitmapNoMemory:
  2331. X        fprintf(stderr, ".twmrc: out of memory\n");
  2332. X        break;
  2333. X
  2334. X    case BitmapOpenFailed:
  2335. X        fprintf(stderr, ".twmrc: failed to open bitmap file\n");
  2336. X        break;
  2337. X
  2338. X    default:
  2339. X        fprintf(stderr,".twmrc: bitmap error = 0x%x\n", status);
  2340. X        break;
  2341. X    }
  2342. X
  2343. X    if (status != BitmapSuccess)
  2344. X    UnknownPm = NULL;
  2345. X}
  2346. SHAR_EOF
  2347. if test 6974 -ne "`wc -c < util.c`"
  2348. then
  2349.     echo shar: error transmitting "util.c" '(should have been 6974 characters)'
  2350. fi
  2351. fi
  2352. if test -f 'version.c'
  2353. then
  2354.     echo shar: will not over-write existing file "version.c"
  2355. else
  2356. echo extracting "version.c"
  2357. sed 's/^X//' >version.c <<'SHAR_EOF'
  2358. X/*****************************************************************************/
  2359. X/**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
  2360. X/**                          Salt Lake City, Utah                           **/
  2361. X/**                                                                         **/
  2362. X/**                           All Rights Reserved                           **/
  2363. X/**                                                                         **/
  2364. X/**    Permission to use, copy, modify, and distribute this software and    **/
  2365. X/**    its documentation  for  any  purpose  and  without  fee is hereby    **/
  2366. X/**    granted, provided that the above copyright notice appear  in  all    **/
  2367. X/**    copies and that both  that  copyright  notice  and  this  permis-    **/
  2368. X/**    sion  notice appear in supporting  documentation,  and  that  the    **/
  2369. X/**    name  of Evans & Sutherland  not be used in advertising or publi-    **/
  2370. X/**    city pertaining to distribution  of the software without  specif-    **/
  2371. X/**    ic, written prior permission.                                        **/
  2372. X/**                                                                         **/
  2373. X/**    EVANS  & SUTHERLAND  DISCLAIMS  ALL  WARRANTIES  WITH  REGARD  TO    **/
  2374. X/**    THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILI-    **/
  2375. X/**    TY AND FITNESS, IN NO EVENT SHALL EVANS &  SUTHERLAND  BE  LIABLE    **/
  2376. X/**    FOR  ANY  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY  DAM-    **/
  2377. X/**    AGES  WHATSOEVER RESULTING FROM  LOSS OF USE,  DATA  OR  PROFITS,    **/
  2378. X/**    WHETHER   IN  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS    **/
  2379. X/**    ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE  OR PER-    **/
  2380. X/**    FORMANCE OF THIS SOFTWARE.                                           **/
  2381. X/*****************************************************************************/
  2382. X
  2383. X/***********************************************************************
  2384. X *
  2385. X * $Header: version.c,v 2.0 88/04/15 07:00:36 tlastran Exp $
  2386. X *
  2387. X * twm version number
  2388. X *
  2389. X * 14-Dec-87 Thomas E. LaStrange        File created
  2390. X *
  2391. X ***********************************************************************/
  2392. X
  2393. Xstatic char RCSinfo[]=
  2394. X"$Header: version.c,v 2.0 88/04/15 07:00:36 tlastran Exp $";
  2395. X
  2396. Xchar *Revision = "$Revision: 2.0 $";
  2397. Xchar *Date = "$Date: 88/04/15 07:00:36 $";
  2398. SHAR_EOF
  2399. if test 2376 -ne "`wc -c < version.c`"
  2400. then
  2401.     echo shar: error transmitting "version.c" '(should have been 2376 characters)'
  2402. fi
  2403. fi
  2404. # end of shell archive
  2405. exit 0
  2406.  
  2407.